<template>
  <div class="form_item-json_param">
    <template v-if="is_info">
      <div v-if="is_list || Object.keys(this_config).length==0" v-html="value_content"></div>
      <template v-else>
        <template v-for="row in this_config" >
          <el-form-item :label="row.label" v-if="is_component(row.type)" :style="form_item_style(row)">
            <div style="width: 100%;">
              <component :is="row.type" name="" :value="this_value[row.name]" v-bind="bind_param(row)" :is_info="true"></component>
            </div>
          </el-form-item>
        </template>
      </template>
    </template>
    <template v-else>
      <input type="hidden" :name="name" :value="value">
      <forms ref="forms" :config="this_config" remove_name="1" @change="onchange" :btns="btns ? btns : []" ></forms>
    </template>
  </div>
</template>

<script>
import s94Mjs from "s94-js";

export default {
  _title_: '自定义参数',
  _can_config_: true,
  _can_form_param_: true,
  name: "json_param",
  props: ['name', 'value', 'config', 'is_info', 'btns', 'size', 'is_list'],
  emits: ['update:value', 'change'],
  data(){
    return {
      need_display: true,
      this_value: {},
      this_config: {},
    }
  },
  methods: {
    is_component(type){
      let map = this.field_type();
      return type in map;
    },
    form_item_style(row){
      let res = (row.style && typeof row.style === 'object') ? row.style : {};
      if (row.block) res['display'] = 'flex';
      if (row.inline) res['display'] = 'inline-flex';
      return res;
    },
    onchange(config){
      let arr = {};
      if (this.$refs.forms.validate() !== true) return this.$message('存在参数不合规范');
      s94Mjs.each(config, function (row){
        arr[row.name] = row.value;
      })
      let v = JSON.stringify(arr);
      this.update_value(v);
    },
    display(){
      this.this_value = this.json_decode(this.value);

      if (typeof(this.config)=='string') {
        this.this_config = this.json_decode(this.config) || {};
      }else {
        this.this_config = this.config || {};
      }
      this.init();
    },
    json_decode(v){
      try {
        v = JSON.parse(v);
        return v && typeof v === 'object' ? v : {};
      } catch (e) {
        return {};
      }
    },
    label(name){
      let config = this.this_config;
      for (const k in config) {
        let row = config[k];
        if (row.name == name && row.label) return row.label;
      }
      return name;
    },
    update_value(v){
      this.need_display = false;
      setTimeout(()=>{this.need_display = true;},5);
      this.$emit('update:value', v);
      this.$emit('change', v);
    },
    init(){
      if (typeof(this.this_value) != 'object' || this.is_info) return;
      setTimeout(()=>{
        if (this.$refs['forms']) this.$refs['forms'].init(this.this_value)
      },20)
    }
  },
  computed: {
    value_content(){
      if (typeof(this.this_value)=='string') return this.this_value;
      var html = "<ul>";
      var this_value = this.this_value;
      if(this.this_config.length>0){
        this.this_config.forEach(function (item){
          html += `<li class="text-ellipsis" title="${this_value[item.name]}">${item.label}：${this_value[item.name]}</li>`;
        })
      }else{
        Object.keys(this.this_value).forEach(function (k){
          let v = this_value[k];
          html += `<li class="text-ellipsis" title="${v}">${k}：${v}</li>`;
        })
      }
      html += "</ul>";
      return html;
    },
  },
  watch: {
    value(v, oldV){
      if (!this.need_display) return;
      this.display();
    },
    config(v, oldV){
      this.display();
    },
    is_info(){
      this.init();
    },
  },
  mounted() {
    this.display();
  }
}
</script>

<style scoped>

</style>